home *** CD-ROM | disk | FTP | other *** search
- /* Read the joystick, and simulated mouse and key "joysticks" */
- // Implemented as pointer drivers. These are good examples of how
- // simple pointer drivers can be.
-
- // ALL code in this file by Dave Stampe, 12/24/93
-
- /*
- This code is part of the VR-386 project, created by Dave Stampe.
- VR-386 is a desendent of REND386, created by Dave Stampe and
- Bernie Roehl. Almost all the code has been rewritten by Dave
- Stampre for VR-386.
-
- Copyright (c) 1994 by Dave Stampe:
- May be freely used to write software for release into the public domain
- or for educational use; all commercial endeavours MUST contact Dave Stampe
- (dstampe@psych.toronto.edu) for permission to incorporate any part of
- this software or source code into their products! Usually there is no
- charge for under 50-100 items for low-cost or shareware products, and terms
- are reasonable. Any royalties are used for development, so equipment is
- often acceptable payment.
-
- ATTRIBUTION: If you use any part of this source code or the libraries
- in your projects, you must give attribution to VR-386 and Dave Stampe,
- and any other authors in your documentation, source code, and at startup
- of your program. Let's keep the freeware ball rolling!
-
- DEVELOPMENT: VR-386 is a effort to develop the process started by
- REND386, improving programmer access by rewriting the code and supplying
- a standard API. If you write improvements, add new functions rather
- than rewriting current functions. This will make it possible to
- include you improved code in the next API release. YOU can help advance
- VR-386. Comments on the API are welcome.
-
- CONTACT: dstampe@psych.toronto.edu
- */
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <dos.h>
- #include <bios.h>
- #include <conio.h>
-
- #include "pointint.h"
- #include "vr_api.h"
- #include "vrconst.h" /* for nouse joy ctrl */
- #include "pcdevice.h" /* for low-level joystick and keyboard */
- #include "intmath.h"
-
-
- extern int joystick_j1; /* raw joystick results */
- extern int joystick_j2; /* modified directly by raw_joystick_read(); */
- extern int joystick_j3; /* you may read these elsewhere for trackers */
- extern int joystick_j4;
- extern int joystick_buttons;
-
- static int joy_ok = 1;
-
- /* This routine reads the joystick, setting x y and buttons */
-
- static int use_pothead = 0; /* used by pot head tracker */
-
- // returns: 0 if OK, 1 if failure, -1 if time to shutoff
-
- static int joyx, joyy, joyb;
- static int jcenter_x, jcenter_y;
-
- static int joystick_read()
- {
- int c, k, jx, jy;
- int ovf = 0;
- int j;
-
- if(!joy_ok) return -1;
-
- c = 0x03; // determine read mask
- if(use_pothead) c |= 0x0C; // force read of second input
-
- for(ovf=0;ovf<30;ovf++) // wait till timeout or success
- {
- if(!raw_joystick_read(c)) break;
- }
-
- if(ovf==30) // not responding! so turn it off
- {
- joyx = joyy = 0;
- joyb = 0;
- joy_ok = 0;
- return -1;
- }
-
- joyb = joystick_buttons;
-
- joyx = joystick_j1-jcenter_x;
- joyy = joystick_j2-jcenter_y;
-
- return 0;
- }
-
- static int joystick_init()
- {
- jcenter_x = jcenter_y = 0;
- joystick_read();
- jcenter_x = joyx;
- jcenter_y = joyy;
- return joystick_read();
- }
-
-
-
- /* This routine returns two bits; bit 0 on => joystick 1 found, bit 1 => joystick 2 */
-
- static int joystick_check(void)
- {
- int c, cc, i, result;
-
- disable();
- outportb(0x201,0xff); /* Trigger joystick */
- c = inportb(0x201);
- c = inportb(0x201);
- c = inportb(0x201);
- enable();
-
- cc = 0;
- for(i=0;i<1000;i++) /* wait a few milliseconds */
- cc |= c ^ inportb(0x201); /* and look for changes */
-
- result = 0;
-
- if (cc & 0x03) result |= 1;
- if (cc & 0x0C) result |= 2;
-
- return result;
- }
-
-
- pconfig joy_pconfig = {
- 65536L, 65536L, 65536L, /* position res: mm/tick in <16.16> */
- 600, 600, 0, -600, -600, 0, /* xyz ranges: */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, /* no rotation */
- 640, 480, /* mouse emulation limits (writable) */
- P_HASB1 | P_HASB2 | P_HASX | P_HASY, /* databits */
- 0, 0, 0, /* modes, nullkey, flexnum */
- 1, 10, 60, /* delay, idelay, reads/sec */
- P_IS2DP | P_IS2D, /* uses */
- "Joystick Driver for navigation"
- };
-
- #define JTHRESHOLD 200
-
- pconfig *joy_driver(int op, POINTER *p, int mode)
- {
- union REGS r;
- int type = FP_OFF(p); /* way to get integer arg. */
-
- switch(op)
- {
- case DRIVER_CMD:
- if (!(type & P_CENTER)) break;
- joystick_init();
- break;
- case DRIVER_INIT:
- if(!joystick_check()) return NULL;
- joystick_init();
- case DRIVER_RESET:
- joyx = joyy = joyb = 0;
- break;
-
- case DRIVER_READ: /* pointer (2DP) read */
- if (mode == P_POINTER)
- {
- p->x = 0; // first threshold for navigation...
- p->y = 0;
- if(!joy_ok) break;
- joystick_read();
- if (abs(joyx)<JTHRESHOLD && abs(joyy)<JTHRESHOLD) goto retbut;
- if (joyx>JTHRESHOLD) joyx -= JTHRESHOLD;
- else
- {
- if (joyx<-JTHRESHOLD) joyx += JTHRESHOLD;
- else joyx = 0;
- }
- if (joyy > JTHRESHOLD) joyy -= JTHRESHOLD;
- else
- {
- if (joyy<-JTHRESHOLD) joyy += JTHRESHOLD;
- else joyy = 0;
- }
- p->x = joyx;
- p->y = joyy;
- retbut:
- p->z = 0;
- p->buttons = joyb;
- }
- break;
- case DRIVER_CHECK:
- if(!joystick_check()) return NULL;
- break;
- case DRIVER_QUIT:
- break;
- }
- return &joy_pconfig;
- }
-
-
-
-
- /************* USE MOUSE TO EMULATE JOYSTICK ***********/
-
- static int oldalt = 0;
- static mjx = 0;
- static mjy = 0;
-
- static int old_mjx = 0;
- static int old_mjy = 0;
-
- #define MJOY_ENABLE 0x1000
- #define MJOY_VELOCITY 0x2000
-
- static int mjoyx, mjoyy, mjoyb;
-
- static imouse_joy(int mode)
- {
- union REGS r;
- int x,y,b;
- int alt;
-
- if (0==(mode&MJOY_ENABLE))
- {
- r.h.ah = 2;
- int86(0x16, &r, &r);
- alt = r.h.al & 8; // look for ALT key (temp mouse on)
- if (alt == 0)
- {
- mjoyx = 0; // no: clear data, exit
- mjoyy = 0;
- mjoyb = 0;
- oldalt = 0;
- return 0;
- }
- else
- if (oldalt == 0) // new alt: reset data
- {
- mjx = 0;
- mjy = 0;
- oldalt = alt;
- }
- }
- r.x.ax = 3; /* read button status */
- int86(0x33, &r, &r);
- {
- int b=0;
- if (r.x.bx & 1) b |= 2;
- if (r.x.bx & 2) b |= 1;
- mjoyb = b;
- }
-
- r.x.ax = 11; /* read motion counters */
- int86(0x33, &r, &r);
- if(0==(mode&MJOY_VELOCITY))
- {
- old_mjx = old_mjy = 0;
- mjx = ((int) r.x.cx); /* MOUSE STEP */
- mjy = ((int) r.x.dx);
-
- }
- else
- {
- if(mjoyb&1) // go back to absolute for rotation
- {
- mjx = ((int) r.x.cx);
- mjy = ((int) r.x.dx);
- }
- else
- {
- mjx = mjy = 0;
- mjx = old_mjx; /* save for reversion */
- mjy = old_mjy;
- mjx += ((int) r.x.cx)>>2; /* SPEED STEP */
- mjy += ((int) r.x.dx)>>2;
- if (mjx < -50) mjx = -50;
- if (mjy < -50) mjy = -50;
- if (mjx > 50) mjx = 50;
- if (mjy > 50) mjy = 50;
- old_mjx = mjx;
- old_mjy = mjy;
- }
- }
- mjoyx = mjx>>1;
- mjoyy = mjy>>1;
- return 1;
- }
-
-
- pconfig mjoy_pconfig = {
- 65536L, 65536L, 65536L, /* position res: mm/tick in <16.16> */
- 50, 50, 50, -50, -50, -50, /* xyz ranges: */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, /* no rotation */
- 640, 480, /* mouse emulation limits (writable) */
- P_HASB1 | P_HASB2 | P_HASX | P_HASY, /* databits */
- 0, 0, 0, /* modes, nullkey, flexnum */
- 1, 10, 60, /* delay, idelay, reads/sec */
- P_IS2DP | P_IS2D, /* uses */
- "Mouse used for navigation"
- };
-
- static int mjoy_mode = 0;
-
- pconfig *mjoy_driver(int op, POINTER *p, int mode)
- {
- union REGS r;
- int type = FP_OFF(p); /* way to get integer arg. */
-
- switch(op)
- {
- case DRIVER_CMD:
- mjoy_mode = type;
- break;
- case DRIVER_INIT:
- case DRIVER_RESET:
- mjoyx = mjoyy = mjoyb = 0;
- mjx = mjy = old_mjx = old_mjy = 0;
- break;
-
- case DRIVER_READ: /* pointer (2DP) read */
- if (mode == P_POINTER)
- {
- imouse_joy(mjoy_mode);
- p->x = mjoyx;
- p->y = mjoyy;
- p->z = 0;
- p->buttons = mjoyb;
- }
- break;
- case DRIVER_CHECK:
- break;
- case DRIVER_QUIT:
- break;
- }
- return &mjoy_pconfig;
- }
-
-
-
- /************ USE KEY MONITOR TO FAKE JOYSTICK **********/
-
- // NOTE: IF SHIFT SEEMS STUCK ON, TURN THE NUM LOCK OFF!
-
- extern int use_keyjoy;
-
- #define KJOY_SCALE 15
-
- static int kmjoyx, kmjoyy, kmjoyb;
-
- static int ikey_joy()
- {
- int x, y, b;
- union REGS regs;
-
- x = y = 0;
- kmjoyx = x;
- kmjoyy = y;
- if(!use_keyjoy) return 0;
-
- if(is_key_down(UP_CURSOR_KEYCODE)) y = -KJOY_SCALE;
- if(is_key_down(DOWN_CURSOR_KEYCODE)) y = KJOY_SCALE;
- if(is_key_down(LEFT_CURSOR_KEYCODE)) x = -KJOY_SCALE;
- if(is_key_down(RIGHT_CURSOR_KEYCODE)) x = KJOY_SCALE;
-
- // use BIOS for shift keys: tricky interactions in format
- regs.h.ah = 2; // this will always work
- int86(0x16, ®s, ®s);
- b = (regs.h.al & 3);
-
- kmjoyx = x;
- kmjoyy = y;
- kmjoyb = b;
-
- if(x || y) return 1;
- else return 0;
- }
-
-
-
- pconfig keymon_pconfig = {
- 65536L, 65536L, 65536L, /* position res: mm/tick in <16.16> */
- 50, 50, 50, -50, -50, -50, /* xyz ranges: */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, /* no rotation */
- 640, 480, /* mouse emulation limits (writable) */
- P_HASB1 | P_HASB2 | P_HASX | P_HASY, /* databits */
- 0, 0, 0, /* modes, nullkey, flexnum */
- 1, 10, 60, /* delay, idelay, reads/sec */
- P_IS2DP | P_IS2D, /* uses */
- "Key monitor for navigation"
- };
-
-
-
- pconfig *keymon_driver(int op, POINTER *p, int mode)
- {
- union REGS r;
- int type = FP_OFF(p); /* way to get integer arg. */
-
-
- switch(op)
- {
- case DRIVER_CMD:
- break;
- case DRIVER_INIT:
- if(!keymon_on) return NULL;
- case DRIVER_RESET:
- kmjoyx = kmjoyy = kmjoyb = 0;
- break;
-
- case DRIVER_READ: /* pointer (2DP) read */
- if (mode == P_POINTER)
- {
- ikey_joy();
- p->x = kmjoyx;
- p->y = kmjoyy;
- p->z = 0;
- p->buttons = kmjoyb;
- }
- break;
- case DRIVER_CHECK:
- if(!keymon_on) return NULL;
- break;
- case DRIVER_QUIT:
- break;
- }
- return &keymon_pconfig;
- }
-
-
-
- /************** KEY PRESSES: COMMANDS FROM KEYBOARD.C ******/
-
-
- #define KPRESS_SCALE 30
-
- static int kjoyx, kjoyy, kjoyb;
-
- // called from handle_motion_keys() in NAVJOY.C
-
- void key_set_move(int x, int y, int b1, int b2)
- {
- kjoyb = (b1?1:0) | (b2?2:0);
- kjoyx = (!x)?0:((x>0)?KPRESS_SCALE:-KPRESS_SCALE);
- kjoyy = (!y)?0:((y>0)?KPRESS_SCALE:-KPRESS_SCALE);
- }
-
- pconfig key_pconfig = {
- 65536L, 65536L, 65536L, /* position res: mm/tick in <16.16> */
- 50, 50, 50, -50, -50, -50, /* xyz ranges: */
- 0, 0, 0, 0, 0, 0, 0, 0, 0, /* no rotation */
- 640, 480, /* mouse emulation limits (writable) */
- P_HASB1 | P_HASB2 | P_HASX | P_HASY, /* databits */
- 0, 0, 0, /* modes, nullkey, flexnum */
- 1, 10, 60, /* delay, idelay, reads/sec */
- P_IS2DP | P_IS2D, /* uses */
- "Default Key Press for navigation"
- };
-
-
-
- pconfig *key_driver(int op, POINTER *p, int mode)
- {
- union REGS r;
- int type = FP_OFF(p); /* way to get integer arg. */
-
- switch(op)
- {
- case DRIVER_CMD:
- break;
- case DRIVER_INIT:
- case DRIVER_RESET:
- kjoyx = kjoyy = kjoyb = 0;
- break;
-
- case DRIVER_READ: /* pointer (2DP) read */
- if (mode == P_POINTER)
- {
- p->x = kjoyx;
- p->y = kjoyy;
- p->z = 0;
- p->buttons = kjoyb;
- kjoyx = kjoyy = 0;
- }
- break;
- case DRIVER_CHECK:
- break;
- case DRIVER_QUIT:
- break;
- }
- return &key_pconfig;
- }
-
-